<?php

namespace app\admin\service;

use think\Collection;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\exception\ValidateException;
use think\Model;
use function jsonError;
use function jsonSuccess;
use function request;
use function validate;

class RequestService
{
    private \think\Request $request;

    public function __construct(){
        $this->request = request();
    }


    /**
     * 查询
     *
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function read($query, bool $isPage=true, string $order='', string $delete='normal'): array|Collection|\think\Paginator
    {
        // 排序
        if ($order){
            $query = $query->order($order);
        }else{
            $field = $this->request->param('field', 'create_time');
            $order = $this->request->param('order', 'desc');
            $query = $query->order($field, $order);
        }


        if ($delete == 'delete'){   // 只查询软删除数据
            $query = $query->onlyTrashed();
        }elseif ($delete == 'full'){
            $query = $query->withTrashed();
        }

        // 查询
        if($isPage){  // 是否分页

            // 每页显示数目
            $pageSize = $this->request->param('pageSize',10);

            $list = $query->paginate($pageSize);

        }else{
            $list = $query->select();
        }

        return $list;
    }


    public function add(Model $model, $validate='', $data=false){
        $req = $this->request;
        if($req->isPost()){
            if (!$data) $data = $this->request->except(['create_time', 'update_time'], 'post');
            // 验证表单数据
            try {
                validate($validate)->check($data);
            } catch (ValidateException $e) {
                // 验证失败 输出错误信息
                return jsonError($e->getError());
            }

            $ser = new CurdService($model);
            $info = $ser->create($data);

            return jsonSuccess([
                'info' => $info,
            ]);

        }
    }

    public function edit(Model $model, $validate='', array|null $data=null){

        if($this->request->isPost()){

            if (!$data) $data = $this->request->except(['create_time', 'update_time'], 'post');

            if(!$id = $data['id']??''){
                return jsonError('无此记录');
            }

            // 验证表单数据
            try {
                validate($validate)->check($data);
            } catch (ValidateException $e) {
                // 验证失败 输出错误信息
                return jsonError($e->getError());
            }

            // 更新数据
            $ser = new CurdService($model);
            $info = $ser->update($data, ['id' => $id]);

            return jsonSuccess([
                'info' => $info
            ]);

        }
    }


    /**
     * * 删除数据时的级联限制，有级联数据的不允许删除
     * rel_id:关联字段
     * rel_model: 关联模型
     * 必须是二维数组：
     * [
     *   ['rel_id'=> 'cate_id', 'rel_model'=>'ArticleCate'],
     * ]
     *
     * @param Model $model
     * @param array $cascades
     * @return array|string|void
     */
    public function del(Model $model, $cascades=[], $ids=null){
        // 更新数据
        $ser = new CurdService($model);
        $req = request();
        if($req->isPost()){
            if (!$ids){
                $ids = $req->param("ids");
            }
            // 是否彻底删除
            $isForce = $this->request->param('is_force');
            $isForce = (bool)$isForce;

            if (is_array($ids)){

                $cascadesIds = [];
                $noCascadesIds = [];

                foreach($ids as $id){
                    // 有关联数据的不允许删除

                    if(count($cascadesIds)>0){
                        foreach ($cascades as $v){
                            $relateId = $v['rel_id'];
                            $relModel = "app\model\\".$v['rel_model'];
                            $data = $relModel::where($relateId, $id)->find();
                            if($data){  // 如果有关联记录不允许删除
                                $cascadesIds[] = $id;
                            }else{
                                $noCascadesIds[] = $id;
                            }

                        }
                    }else{
                        $noCascadesIds = $ids;
                    }


                }

                // 删除
                $ser->destroy($noCascadesIds, $isForce);

                if(count($cascadesIds) > 0){
                    return jsonError('删除成功，部分记录被占用无法删除');
                }else{
                    return jsonSuccess('删除成功');
                }

            }else{

                foreach ($cascades as $v){
                    $relateId = $v['rel_id'];
                    $relModel = "app\model\\".$v['rel_model'];
                    $data = $relModel::where($relateId, $ids)->find();
                    if($data){  // 如果有关联记录不允许删除
                       return jsonError('该记录被占用无法删除');
                    }

                }

                // 更新数据
                $ser = new CurdService($model);
                $ser->destroy($ids, $isForce);
                return jsonSuccess('删除成功');
            }

        }
    }

    public function getPostData(){
        return $this->request->except(['create_time', 'update_time'], 'post');
    }

}
